#pragma once
#include "SehnsuchtPrecompiled.hxx"

namespace Sehnsucht
{
	
	// Helper class that initializes DirectX APIs for both 2D and 3D rendering
	// (for Windows Phone 8 only D3D API is available).
	ref_class_decl DirectXBase
	{
#ifndef REIGN_DESKTOP // For Nondesktop apps Win8 API is used

		typedef Platform::Agile<Windows::UI::Core::CoreWindow> CoreWindowHolder;
		typedef Windows::UI::Core::CoreWindow^ CoreWindowPtr;
		typedef Windows::Foundation::Size Size;
		typedef Windows::Foundation::Rect Rect;

#else // D2D is available for Desktop apps

		typedef HWND CoreWindowHolder;
		typedef HWND CoreWindowPtr;
		typedef D2D_RECT_F Rect;
		typedef D2D_SIZE_F Size;

#endif

		typedef Microsoft::WRL::ComPtr<ID3D11Device1> DirectXDevice3;
		typedef DirectXDevice3::InterfaceType *DirectXDevice3Ptr;
		typedef Microsoft::WRL::ComPtr<ID3D11DeviceContext1> DirectXContext3;
		typedef DirectXContext3::InterfaceType *DirectXContext3Ptr;
		typedef Microsoft::WRL::ComPtr<IDXGISwapChain1> DirectXSwapChain;
		typedef DirectXSwapChain::InterfaceType *DirectXSwapChainPtr;
		typedef Microsoft::WRL::ComPtr<ID3D11RenderTargetView> DirectXRenderTargetView;
		typedef DirectXRenderTargetView::InterfaceType *DirectXRenderTargetViewPtr;
		typedef Microsoft::WRL::ComPtr<ID3D11DepthStencilView> DirectXDepthStencilView;
		typedef DirectXDepthStencilView::InterfaceType *DirectXDepthStencilViewPtr;
		typedef D3D_FEATURE_LEVEL DirectXFeatureLevel;
		typedef D3D_DRIVER_TYPE DirectXDriver;

#ifndef REIGN_PHONE

		typedef Microsoft::WRL::ComPtr<IDWriteFactory1> DirectXDWriteFactory;
		typedef DirectXDWriteFactory::InterfaceType *DirectXDWriteFactoryPtr;
		typedef Microsoft::WRL::ComPtr<IWICImagingFactory2> DirectXWICFactory;
		typedef DirectXWICFactory::InterfaceType *DirectXWICFactoryPtr;
		typedef Microsoft::WRL::ComPtr<ID2D1Factory1> DirectXFactory2;
		typedef DirectXFactory2::InterfaceType *DirectXFactory2Ptr;
		typedef Microsoft::WRL::ComPtr<ID2D1Device> DirectXDevice2;
		typedef DirectXDevice2::InterfaceType *DirectXDevice2Ptr;
		typedef Microsoft::WRL::ComPtr<ID2D1DeviceContext> DirectXContext2;
		typedef DirectXContext2::InterfaceType *DirectXContext2Ptr;
		typedef Microsoft::WRL::ComPtr<ID2D1Bitmap1> DirectXBitmap;
		typedef DirectXBitmap::InterfaceType *DirectXBitmapPtr;

#endif

	public_owned_access:

		DirectXBase();

	protected_owned_access:

		// Initialize the DirectX resources required to run.
		void Initialize( 
			_In_ DirectXBase::CoreWindowPtr pWindow,									// Window wrapper pointer
			_In_ Reign::Standard::Float32 fDpi = SEHNSUCHT_DESIGN_SCALE_DPI_PIXELS,		// Display DPI
			_In_opt_ DirectXBase::DirectXDriver eDriver = D3D_DRIVER_TYPE_HARDWARE		// DirectX Driver Type (Hardware by default)
			);

		// Recreate all device resources and set them back to the current state.
		void HandleDeviceLost();
		void ValidateDevice();

		void CreateDeviceIndependentResources();
		void CreateDeviceResources( _In_opt_ DirectXBase::DirectXDriver eDriver = D3D_DRIVER_TYPE_HARDWARE );
		void Present();

		void CreateWindowSizeDependentResources();
		void UpdateForWindowSizeChange();
		void SetDpi( _In_ Float32 fDpi = SEHNSUCHT_DESIGN_SCALE_DPI_PIXELS );

	protected_owned_access:

		DirectXBase::CoreWindowHolder			m_Window;

#ifndef REIGN_PHONE

		/// DirectWrite & Windows Imaging Component Objects.

		DirectXBase::DirectXDWriteFactory       m_DwFactory2;
		DirectXBase::DirectXWICFactory			m_WicFactory2;

		/// Direct2D Rendering Objects. Required for 2D.

		DirectXBase::DirectXFactory2			m_Factory2;
		DirectXBase::DirectXDevice2             m_Device2;
		DirectXBase::DirectXContext2			m_Context2;
		DirectXBase::DirectXBitmap				m_TargetBitmap2;

#endif

		/// DirectX Core Objects. Required for 2D and 3D.

		DirectXBase::DirectXDevice3				m_Device3;
		DirectXBase::DirectXContext3			m_Context3;
		DirectXBase::DirectXSwapChain			m_SwapChain3;
		DirectXBase::DirectXRenderTargetView	m_RenderTargetView3;

		/// Direct3D Rendering Objects. Required for 3D.

		DirectXBase::DirectXDepthStencilView	m_DepthStencilView3;

		DirectXFeatureLevel                     m_FeatureLevel3;
		DirectXBase::Size                       m_RenderTargetSize;
		DirectXBase::Rect                       m_WindowBounds;
		Reign::Standard::Float32                m_fDpi;

#ifdef REIGN_METRO
		Reign::Standard::Bool                   m_bWindowSizeChangeInProgress;
#endif

		DirectXDriver m_eDriver;

	};
};